/**
 * Chat组件 - AI聊天界面
 * 功能包括：消息发送/接收、语音合成、图片上传、表情选择、消息编辑/撤回等
 */

import React, { useState, useRef, useEffect } from 'react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import './Chat.css'
import { chatCompletion, streamChatCompletion } from '../../api/moonshot'
import type { MoonshotMessage } from '../../api/moonshot'

/**
 * Markdown消息渲染组件
 * 用于渲染AI助手的Markdown格式回复，支持表格、代码块等GitHub风格Markdown
 */
const MarkdownMessage: React.FC<{ content: string }> = ({ content }) => {
  return (
    <div className="markdown-content">
      <ReactMarkdown remarkPlugins={[remarkGfm]}>
        {content}
      </ReactMarkdown>
    </div>
  )
}

/**
 * 消息数据结构接口
 * 定义聊天消息的完整数据结构
 */
interface Message {
  id: string                    // 消息唯一标识符
  content: string              // 消息文本内容
  type: 'user' | 'assistant'  // 消息类型：用户发送或AI助手回复
  timestamp: Date              // 消息发送时间戳
  canRecall?: boolean          // 是否可以撤回（仅用户消息）
  isEditing?: boolean          // 是否正在编辑状态
  imageUrl?: string            // 图片URL（用于显示图片消息）
  imageFile?: File             // 图片文件对象（用于上传）
}

/**
 * Chat组件属性接口
 * 定义组件接收的外部属性
 */
interface ChatProps {
  inputRef?: React.RefObject<HTMLTextAreaElement>;  // 外部传入的输入框引用（用于语音输入）
  speechResult?: string;                             // 语音识别结果文本
  onNewAIMessage?: (content: string) => void;        // 新AI回复时的回调函数
}

/**
 * Chat组件主函数
 * 实现完整的AI聊天功能，包括消息交互、语音合成、图片处理等
 */
function Chat({ inputRef: externalInputRef, speechResult, onNewAIMessage }: ChatProps) {
  // ==================== 状态管理 ====================
  
  /**
   * 消息列表状态
   * 存储所有聊天消息，包括用户输入和AI回复
   */
  const [messages, setMessages] = useState<Message[]>([
    {
      id: '1',
      content: '你好！我是你的AI助手，有什么可以帮助你的吗？我可以回答你的问题、帮你分析数据、或者陪你聊天。',
      type: 'assistant',
      timestamp: new Date()
    }
  ])
  
  /**
   * 输入框相关状态
   */
  const [inputValue, setInputValue] = useState('')           // 输入框当前内容
  const [isLoading, setIsLoading] = useState(false)          // 是否正在发送消息（显示加载状态）
  
  /**
   * UI交互状态
   */
  const [showRecallTip, setShowRecallTip] = useState(false)     // 是否显示撤回成功提示
  const [showEmojiPicker, setShowEmojiPicker] = useState(false) // 是否显示表情选择器面板
  const [editingMessageId, setEditingMessageId] = useState<string | null>(null) // 当前正在编辑的消息ID
  const [editValue, setEditValue] = useState('')               // 编辑框的临时内容
  const [showSearch, setShowSearch] = useState(false)          // 是否显示搜索功能
  const [searchQuery, setSearchQuery] = useState('')           // 搜索框的关键词
  const [showMenu, setShowMenu] = useState(false)              // 是否显示设置菜单
  
  /**
   * 图片相关状态
   */
  const [imagePreview, setImagePreview] = useState<string | null>(null) // 图片预览的URL（用于发送前预览）
  const [editingImage, setEditingImage] = useState<string | null>(null) // 编辑消息时的图片URL
  const [showImageModal, setShowImageModal] = useState<string | null>(null) // 图片模态框显示的图片URL（大图预览）
  
  /**
   * 语音合成相关状态
   */
  const [isSpeaking, setIsSpeaking] = useState(false)         // 是否正在播放语音
  const [speechRate, setSpeechRate] = useState(1)             // 语音播放速度（0.5-2.0倍速）
  const [speechPitch, setSpeechPitch] = useState(1)           // 语音音调（0.5-2.0倍调）
  const [selectedVoice, setSelectedVoice] = useState<SpeechSynthesisVoice | null>(null) // 当前选中的语音
  const [availableVoices, setAvailableVoices] = useState<SpeechSynthesisVoice[]>([]) // 系统可用的语音列表
  const [autoSpeak, setAutoSpeak] = useState(false)           // 是否自动播放AI回复
  const [clickToSpeak, setClickToSpeak] = useState(false)     // 是否开启点击消息转语音功能
  const [speakingMessageId, setSpeakingMessageId] = useState<string | null>(null) // 当前正在播放语音的消息ID
  
  /**
   * API相关状态
   */
  const [useStreaming, setUseStreaming] = useState(false)     // 是否使用流式响应（实时显示AI回复）
  const [apiKeyStatus, setApiKeyStatus] = useState<'checking' | 'valid' | 'invalid' | 'missing'>('checking') // API密钥状态检查
  
  /**
   * DOM引用
   */
  const messagesEndRef = useRef<HTMLDivElement>(null)         // 消息列表底部引用（用于自动滚动到底部）
  const inputRef = useRef<HTMLTextAreaElement>(null)          // 输入框引用
  const fileInputRef = useRef<HTMLInputElement>(null)         // 文件上传输入框引用
  const imageInputRef = useRef<HTMLInputElement>(null)        // 图片上传输入框引用
  
  // 使用外部ref或内部ref（优先使用外部传入的ref）
  const finalInputRef = externalInputRef || inputRef;



  // ==================== 副作用钩子 ====================
  
  /**
   * 初始化语音合成功能
   * 获取系统可用语音列表，优先选择中文语音
   */
  useEffect(() => {
    const initSpeechSynthesis = () => {
      if ('speechSynthesis' in window) {
        const voices = window.speechSynthesis.getVoices();
        setAvailableVoices(voices);
        
        // 优先选择中文语音作为默认语音
        const chineseVoice = voices.find(voice => 
          voice.lang.includes('zh') || voice.lang.includes('cmn')
        );
        setSelectedVoice(chineseVoice || voices[0] || null);
        
        // 监听语音列表变化事件（某些浏览器需要异步加载语音）
        window.speechSynthesis.onvoiceschanged = () => {
          const updatedVoices = window.speechSynthesis.getVoices();
          setAvailableVoices(updatedVoices);
          if (!selectedVoice) {
            const chineseVoice = updatedVoices.find(voice => 
              voice.lang.includes('zh') || voice.lang.includes('cmn')
            );
            setSelectedVoice(chineseVoice || updatedVoices[0] || null);
          }
        };
      }
    };

    initSpeechSynthesis();
  }, [selectedVoice]);

  /**
   * 检查API密钥配置状态
   * 验证Moonshot API密钥是否正确配置
   */
  useEffect(() => {
    const checkApiKey = () => {
      const apiKey = import.meta.env.VITE_MOONSHOT_API_KEY;
      if (!apiKey || apiKey === 'your_moonshot_api_key_here') {
        setApiKeyStatus('missing');
      } else {
        setApiKeyStatus('valid');
      }
    };

    checkApiKey();
  }, []);

  /**
   * 接收语音识别结果
   * 当外部传入语音识别结果时，自动填充到输入框
   */
  useEffect(() => {
    if (speechResult && speechResult.trim()) {
      console.log('Chat组件接收到语音识别结果:', speechResult);
      setInputValue(speechResult);
      
      // 触发input事件以确保React状态正确更新
      if (finalInputRef.current) {
        const event = new Event('input', { bubbles: true });
        finalInputRef.current.dispatchEvent(event);
      }
    }
  }, [speechResult, finalInputRef]);

  /**
   * 自动滚动到消息列表底部
   * 确保新消息始终可见
   */
  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }

  /**
   * 消息列表变化时自动滚动到底部
   */
  useEffect(() => {
    scrollToBottom()
  }, [messages])

  /**
   * 全局键盘和点击事件监听
   * 处理快捷键和点击外部关闭弹窗
   */
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      // Ctrl+Z (Windows) 或 Cmd+Z (Mac) 撤回上一条消息
      if ((e.ctrlKey || e.metaKey) && e.key === 'z') {
        e.preventDefault()
        handleRecallLastMessage()
      }
      // Escape 键关闭各种弹窗和编辑状态
      if (e.key === 'Escape') {
        setShowEmojiPicker(false)
        setShowImageModal(null)
        if (editingMessageId) {
          cancelEdit()
        }
      }
    }

    // 点击外部区域关闭表情选择器
    const handleClickOutside = (e: MouseEvent) => {
      const target = e.target as Element
      if (showEmojiPicker && 
          !target.closest('.emoji-picker') && 
          !target.closest('.emoji-btn') &&
          !target.closest('.input-actions')) {
        setShowEmojiPicker(false)
      }
    }

    document.addEventListener('keydown', handleKeyDown)
    document.addEventListener('click', handleClickOutside)
    
    return () => {
      document.removeEventListener('keydown', handleKeyDown)
      document.removeEventListener('click', handleClickOutside)
    }
  }, [messages, editingMessageId, showEmojiPicker])

  // ==================== 核心功能函数 ====================
  
  /**
   * 发送消息的主要函数
   * 处理用户消息发送、AI回复获取、流式响应等核心功能
   */
  const handleSend = async () => {
    // 验证输入内容和加载状态
    if (!inputValue.trim() || isLoading) return

    // 检查API密钥配置状态
    if (apiKeyStatus !== 'valid') {
      const errorMessage: Message = {
        id: (Date.now() + 1).toString(),
        content: '⚠️ API密钥未配置，无法使用AI功能。请在项目根目录创建 .env.local 文件并添加有效的Moonshot API密钥。',
        type: 'assistant',
        timestamp: new Date()
      }
      setMessages(prev => [...prev, errorMessage])
      return
    }

    // 创建并添加用户消息到列表
    const userMessage: Message = {
      id: Date.now().toString(),
      content: inputValue.trim(),
      type: 'user',
      timestamp: new Date(),
      canRecall: true  // 用户消息可以撤回
    }

    setMessages(prev => [...prev, userMessage])
    setInputValue('')  // 清空输入框
    setIsLoading(true) // 显示加载状态

    try {
      // 构建消息历史记录（用于API调用）
      const messageHistory: MoonshotMessage[] = messages
        .filter(msg => msg.type === 'user' || msg.type === 'assistant')
        .map(msg => ({
          role: msg.type === 'user' ? 'user' : 'assistant',
          content: msg.content
        }));

      // 将当前用户消息添加到历史记录中
      messageHistory.push({
        role: 'user',
        content: userMessage.content
      });

      if (useStreaming) {
        // 使用流式响应模式（实时显示AI回复）
        const assistantMessageId = (Date.now() + 1).toString();
        const assistantMessage: Message = {
          id: assistantMessageId,
          content: '',  // 初始为空，逐步填充
          type: 'assistant',
          timestamp: new Date()
        };
        
        setMessages(prev => [...prev, assistantMessage]);

        // 调用流式API，实时接收AI回复
        await streamChatCompletion(
          messageHistory,
          {
            model: 'moonshot-v1-8k',
            temperature: 0.7,
            max_tokens: 1000
          },
          (chunk: string) => {
            // 实时更新消息内容（逐字显示）
            setMessages(prev => prev.map(msg => 
              msg.id === assistantMessageId 
                ? { ...msg, content: msg.content + chunk }
                : msg
            ));
          }
        );

        // 流式响应完成后的处理
        const finalMessage = messages.find(msg => msg.id === assistantMessageId);
        if (finalMessage && autoSpeak) {
          speakText(finalMessage.content, assistantMessageId);
        }
        // 调用外部回调函数
        if (onNewAIMessage && finalMessage) {
          onNewAIMessage(finalMessage.content);
        }
      } else {
        // 使用普通响应模式（等待完整回复）
        const response = await chatCompletion(messageHistory, {
          model: 'moonshot-v1-8k',
          temperature: 0.7,
          max_tokens: 1000
        });

        const assistantContent = response.choices[0]?.message?.content || '抱歉，我现在无法回答。';
        
        const assistantMessage: Message = {
          id: (Date.now() + 1).toString(),
          content: assistantContent,
          type: 'assistant',
          timestamp: new Date()
        }
        
        setMessages(prev => [...prev, assistantMessage])
        
        // 自动播放AI回复（如果开启）
        if (autoSpeak) {
          speakText(assistantMessage.content, assistantMessage.id);
        }
        // 调用外部回调函数
        if (onNewAIMessage && assistantMessage.type === 'assistant') {
          onNewAIMessage(assistantMessage.content);
        }
      }
    } catch (error: unknown) {
      console.error('API请求失败:', error);
      
      // 显示错误消息给用户
      const errorMessage: Message = {
        id: (Date.now() + 1).toString(),
        content: `抱歉，请求失败: ${error instanceof Error ? error.message : '未知错误'}`,
        type: 'assistant',
        timestamp: new Date()
      }
      setMessages(prev => [...prev, errorMessage])
    } finally {
      setIsLoading(false)  // 结束加载状态
    }
  }

  /**
   * 撤回指定ID的消息
   * @param messageId 要撤回的消息ID
   */
  const handleRecall = (messageId: string) => {
    setMessages(prev => prev.filter(msg => msg.id !== messageId))
    showRecallFeedback()
  }

  /**
   * 撤回上一条用户消息
   * 支持Ctrl+Z快捷键调用
   */
  const handleRecallLastMessage = () => {
    const userMessages = messages.filter(msg => msg.type === 'user' && msg.canRecall)
    if (userMessages.length > 0) {
      const lastUserMessage = userMessages[userMessages.length - 1]
      handleRecall(lastUserMessage.id)
    }
  }

  /**
   * 显示撤回成功反馈提示
   * 2秒后自动消失
   */
  const showRecallFeedback = () => {
    setShowRecallTip(true)
    setTimeout(() => {
      setShowRecallTip(false)
    }, 2000)
  }

  /**
   * 开始编辑指定消息
   * @param messageId 要编辑的消息ID
   * @param content 消息当前内容
   */
  const handleEdit = (messageId: string, content: string) => {
    setEditingMessageId(messageId)
    setEditValue(content)
  }

  /**
   * 保存编辑内容
   * 更新消息内容并退出编辑模式
   */
  const saveEdit = () => {
    if (editValue.trim() && editingMessageId) {
      setMessages(prev => prev.map(msg => 
        msg.id === editingMessageId 
          ? { ...msg, content: editValue.trim() }
          : msg
      ))
      setEditingMessageId(null)
      setEditValue('')
    }
  }

  /**
   * 取消编辑
   * 退出编辑模式，不保存更改
   */
  const cancelEdit = () => {
    setEditingMessageId(null)
    setEditValue('')
    setEditingImage(null)
  }

  /**
   * 处理键盘事件
   * Enter键发送消息，Shift+Enter换行
   */
  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      if (editingMessageId) {
        saveEdit()  // 编辑模式下保存编辑
      } else {
        handleSend()  // 正常模式下发送消息
      }
    }
  }

  /**
   * 处理文件上传
   * 显示文件信息作为消息
   */
  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file) {
      const userMessage: Message = {
        id: Date.now().toString(),
        content: `📎 ${file.name} (${(file.size / 1024).toFixed(1)}KB)`,
        type: 'user',
        timestamp: new Date(),
        canRecall: true
      }
      setMessages(prev => [...prev, userMessage])
    }
    // 清空文件输入框，允许重复选择同一文件
    if (fileInputRef.current) {
      fileInputRef.current.value = ''
    }
  }

  /**
   * 处理图片上传
   * 读取图片文件并显示预览
   */
  const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file && file.type.startsWith('image/')) {
      const reader = new FileReader()
      reader.onload = (event) => {
        const imageUrl = event.target?.result as string
        setImagePreview(imageUrl)  // 设置图片预览
      }
      reader.readAsDataURL(file)  // 将文件读取为Data URL
    }
    // 清空图片输入框，允许重复选择同一图片
    if (imageInputRef.current) {
      imageInputRef.current.value = ''
    }
  }

  /**
   * 发送图片消息
   * 将预览的图片作为消息发送
   * @param imageUrl 图片URL
   * @param content 图片描述文本
   */
  const sendImageMessage = (imageUrl: string, content: string = '') => {
    const userMessage: Message = {
      id: Date.now().toString(),
      content: content || '📷 图片',
      type: 'user',
      timestamp: new Date(),
      canRecall: true,
      imageUrl: imageUrl
    }
    setMessages(prev => [...prev, userMessage])
    setImagePreview(null)  // 清空预览
  }

  /**
   * 编辑带图片的消息
   * 进入编辑模式并保留图片
   * @param messageId 消息ID
   * @param currentImageUrl 当前图片URL
   */
  const handleEditImage = (messageId: string, currentImageUrl: string) => {
    setEditingMessageId(messageId)
    setEditingImage(currentImageUrl)
  }

  /**
   * 保存带图片的编辑
   * 更新消息内容和图片
   */
  const saveImageEdit = () => {
    if (editValue.trim() && editingMessageId && editingImage) {
      setMessages(prev => prev.map(msg => 
        msg.id === editingMessageId 
          ? { ...msg, content: editValue.trim(), imageUrl: editingImage }
          : msg
      ))
      setEditingMessageId(null)
      setEditValue('')
      setEditingImage(null)
    }
  }

  /**
   * 移除图片预览
   * 清空图片预览和编辑图片
   */
  const removeImage = () => {
    setImagePreview(null)
    setEditingImage(null)
  }

  /**
   * 添加表情到输入框或编辑框
   * 根据当前状态决定添加到哪个输入框
   * @param emoji 表情符号
   */
  const addEmoji = (emoji: string) => {
    if (editingMessageId) {
      setEditValue(prev => prev + emoji)  // 编辑模式下添加到编辑框
    } else {
      setInputValue(prev => prev + emoji)  // 正常模式下添加到输入框
    }
    setShowEmojiPicker(false)  // 关闭表情选择器
  }

  /**
   * 切换表情选择器显示状态
   * 防止事件冒泡
   */
  const toggleEmojiPicker = (e: React.MouseEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setShowEmojiPicker(prev => !prev)
  }

  // ==================== 工具函数 ====================
  
  /**
   * 格式化时间显示
   * 将Date对象格式化为中文时间格式（HH:MM）
   */
  const formatTime = (date: Date) => {
    return date.toLocaleTimeString('zh-CN', { 
      hour: '2-digit', 
      minute: '2-digit' 
    })
  }

  /**
   * 检查是否可以撤回上一条消息
   * 只有当存在可撤回的用户消息时才显示撤回按钮
   */
  const canRecallLastMessage = messages.some(msg => msg.type === 'user' && msg.canRecall)

  /**
   * 根据搜索关键词过滤消息
   * 支持不区分大小写的文本搜索
   */
  const filteredMessages = searchQuery 
    ? messages.filter(msg => msg.content.toLowerCase().includes(searchQuery.toLowerCase()))
    : messages

  /**
   * 消息统计信息
   * 计算总消息数、用户消息数、AI回复数
   */
  const messageStats = {
    total: messages.length,
    user: messages.filter(msg => msg.type === 'user').length,
    assistant: messages.filter(msg => msg.type === 'assistant').length
  }

  // ==================== 语音合成功能 ====================
  
  /**
   * 语音合成功能
   * 将文本转换为语音并播放
   * @param text 要播放的文本内容
   * @param messageId 消息ID（用于标识正在播放的消息）
   */
  const speakText = (text: string, messageId?: string) => {
    if ('speechSynthesis' in window && selectedVoice) {
      // 停止当前正在播放的语音
      window.speechSynthesis.cancel();
      
      // 创建语音合成对象
      const utterance = new SpeechSynthesisUtterance(text);
      utterance.voice = selectedVoice;      // 设置语音
      utterance.rate = speechRate;          // 设置语速
      utterance.pitch = speechPitch;        // 设置音调
      utterance.lang = selectedVoice.lang;  // 设置语言
      
      // 设置播放状态
      setIsSpeaking(true);
      if (messageId) {
        setSpeakingMessageId(messageId);
      }
      
      // 语音开始播放事件
      utterance.onstart = () => {
        setIsSpeaking(true);
        if (messageId) {
          setSpeakingMessageId(messageId);
        }
      };
      
      // 语音播放结束事件
      utterance.onend = () => {
        setIsSpeaking(false);
        setSpeakingMessageId(null);
      };
      
      // 语音播放错误事件
      utterance.onerror = (event) => {
        console.error('语音合成错误:', event);
        setIsSpeaking(false);
        setSpeakingMessageId(null);
      };
      
      // 开始播放语音
      window.speechSynthesis.speak(utterance);
    }
  };

  /**
   * 点击消息播放语音
   * 当开启点击转语音功能时，点击消息可播放其内容
   */
  const handleMessageClick = (message: Message) => {
    if (clickToSpeak && message.content && !isSpeaking) {
      speakText(message.content, message.id);
    }
  };

  /**
   * 播放所有AI回复
   * 将所有AI助手的回复合并后播放
   */
  const playAllAIReplies = () => {
    const aiMessages = messages.filter(msg => msg.type === 'assistant' && msg.content);
    if (aiMessages.length > 0) {
      const combinedText = aiMessages.map(msg => msg.content).join('。');
      speakText(combinedText);
    }
  };

  /**
   * 停止语音播放
   * 取消当前正在播放的语音
   */
  const stopSpeaking = () => {
    if ('speechSynthesis' in window) {
      window.speechSynthesis.cancel();
      setIsSpeaking(false);
      setSpeakingMessageId(null);
    }
  };

  // ==================== 聊天记录管理 ====================
  
  /**
   * 清空聊天记录
   * 重置为初始欢迎消息
   */
  const clearChat = () => {
    setMessages([{
      id: '1',
      content: '你好！我是你的AI助手，有什么可以帮助你的吗？我可以回答你的问题、帮你分析数据、或者陪你聊天。',
      type: 'assistant',
      timestamp: new Date()
    }])
    setShowMenu(false)
  }

  /**
   * 导出聊天记录
   * 将聊天记录导出为JSON文件
   */
  const exportChat = () => {
    const chatData = messages.map(msg => ({
      time: msg.timestamp.toLocaleString(),
      type: msg.type === 'user' ? '用户' : 'AI助手',
      content: msg.content
    }))
    
    // 创建JSON文件并下载
    const blob = new Blob([JSON.stringify(chatData, null, 2)], { type: 'application/json' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `chat-${new Date().toISOString().split('T')[0]}.json`
    a.click()
    URL.revokeObjectURL(url)  // 释放内存
    setShowMenu(false)
  }

  // ==================== 组件渲染 ====================
  
  return (
    <div className="chat-container">
      {/* 聊天头部 */}
      <div className="chat-header">
        <div className="chat-title">
          <div className="chat-avatar">
            <div className="avatar-icon">🤖</div>
          </div>
          <div className="chat-info">
            <h3>AI助手</h3>
            <span className={`status ${apiKeyStatus === 'valid' ? 'online' : 'offline'}`}>
              {apiKeyStatus === 'valid' ? '在线' : 'API密钥未配置'}
            </span>
          </div>
        </div>
        <div className="chat-actions">
          {/* 语音控制按钮 */}
          <button 
            className={`action-btn ${isSpeaking ? 'speaking' : ''}`}
            onClick={isSpeaking ? stopSpeaking : () => speakText('你好！我是你的AI助手，有什么可以帮助你的吗？')}
            title={isSpeaking ? "停止语音" : "播放语音"}
          >
            <span>{isSpeaking ? '🔇' : '🔊'}</span>
          </button>
          
          <button 
            className={`action-btn ${autoSpeak ? 'active' : ''}`}
            onClick={() => setAutoSpeak(!autoSpeak)}
            title={autoSpeak ? "关闭自动语音" : "开启自动语音"}
          >
            <span>🎵</span>
          </button>
          
          <button 
            className={`action-btn ${clickToSpeak ? 'active' : ''}`}
            onClick={() => setClickToSpeak(!clickToSpeak)}
            title={clickToSpeak ? "关闭点击转语音" : "开启点击转语音"}
          >
            <span>👆</span>
          </button>
          
          <button 
            className={`action-btn ${useStreaming ? 'active' : ''}`}
            onClick={() => setUseStreaming(!useStreaming)}
            title={useStreaming ? "关闭流式响应" : "开启流式响应"}
          >
            <span>🌊</span>
          </button>
          
          {/* 撤回上一条消息按钮 */}
          {canRecallLastMessage && (
            <button 
              className="action-btn recall-last-btn"
              onClick={handleRecallLastMessage}
              title="撤回上一条消息 (Ctrl+Z)"
            >
              <span>↶</span>
            </button>
          )}
          <button 
            className="action-btn"
            onClick={() => setShowSearch(!showSearch)}
            title="搜索消息"
          >
            <span>🔍</span>
          </button>
          <button 
            className="action-btn"
            onClick={() => setShowMenu(!showMenu)}
            title="更多选项"
          >
            <span>⋮</span>
          </button>
        </div>
      </div>

      {/* 搜索栏 */}
      {showSearch && (
        <div className="search-container">
          <input
            type="text"
            placeholder="搜索消息..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="search-input"
          />
          {searchQuery && (
            <button 
              className="clear-search-btn"
              onClick={() => setSearchQuery('')}
            >
              ✕
            </button>
          )}
        </div>
      )}

      {/* 菜单 */}
      {showMenu && (
        <div className="menu-overlay" onClick={() => setShowMenu(false)}>
          <div className="menu-content" onClick={e => e.stopPropagation()}>
            <div className="menu-header">
              <h4>聊天选项</h4>
              <button className="close-menu-btn" onClick={() => setShowMenu(false)}>
                ✕
              </button>
            </div>
            <div className="menu-stats">
              <div className="stat-item">
                <span>总消息: {messageStats.total}</span>
              </div>
              <div className="stat-item">
                <span>用户: {messageStats.user}</span>
              </div>
              <div className="stat-item">
                <span>AI助手: {messageStats.assistant}</span>
              </div>
            </div>
            <div className="menu-actions">
              <button className="menu-btn" onClick={exportChat}>
                📤 导出聊天记录
              </button>
              <button className="menu-btn" onClick={playAllAIReplies}>
                🔊 播放所有AI回复
              </button>
              <button className="menu-btn danger" onClick={clearChat}>
                🗑️ 清空聊天记录
              </button>
            </div>
            
            {/* 语音功能说明 */}
            <div className="voice-features">
              <h5>语音功能</h5>
              <div className="feature-item">
                <span className="feature-icon">🔊</span>
                <span className="feature-text">手动播放语音</span>
              </div>
              <div className="feature-item">
                <span className="feature-icon">🎵</span>
                <span className="feature-text">自动播放AI回复</span>
                <span className={`feature-status ${autoSpeak ? 'active' : 'inactive'}`}>
                  {autoSpeak ? '已开启' : '已关闭'}
                </span>
              </div>
              <div className="feature-item">
                <span className="feature-icon">👆</span>
                <span className="feature-text">点击消息转语音</span>
                <span className={`feature-status ${clickToSpeak ? 'active' : 'inactive'}`}>
                  {clickToSpeak ? '已开启' : '已关闭'}
                </span>
              </div>
            </div>
            
            {/* API功能说明 */}
            <div className="api-features">
              <h5>API功能</h5>
              <div className="feature-item">
                <span className="feature-icon">🌊</span>
                <span className="feature-text">流式响应</span>
                <span className={`feature-status ${useStreaming ? 'active' : 'inactive'}`}>
                  {useStreaming ? '已开启' : '已关闭'}
                </span>
              </div>
              <div className="feature-item">
                <span className="feature-icon">🤖</span>
                <span className="feature-text">Moonshot AI</span>
                <span className={`feature-status ${apiKeyStatus === 'valid' ? 'active' : 'inactive'}`}>
                  {apiKeyStatus === 'valid' ? '已连接' : '未配置'}
                </span>
              </div>
              {apiKeyStatus !== 'valid' && (
                <div className="api-key-notice">
                  <p>⚠️ 需要配置API密钥才能使用AI功能</p>
                  <p>请在项目根目录创建 .env.local 文件并添加:</p>
                  <code>VITE_MOONSHOT_API_KEY=你的实际API密钥</code>
                </div>
              )}
            </div>
            
            {/* 语音设置 */}
            <div className="voice-settings">
              <h5>语音设置</h5>
              <div className="voice-controls">
                <label className="voice-control-item">
                  <span>语速:</span>
                  <input
                    type="range"
                    min="0.5"
                    max="2"
                    step="0.1"
                    value={speechRate}
                    onChange={(e) => setSpeechRate(Number(e.target.value))}
                    className="voice-slider"
                  />
                  <span>{speechRate}x</span>
                </label>
                
                <label className="voice-control-item">
                  <span>音调:</span>
                  <input
                    type="range"
                    min="0.5"
                    max="2"
                    step="0.1"
                    value={speechPitch}
                    onChange={(e) => setSpeechPitch(Number(e.target.value))}
                    className="voice-slider"
                  />
                  <span>{speechPitch}x</span>
                </label>
                
                <label className="voice-control-item">
                  <span>语音:</span>
                  <select
                    value={selectedVoice?.name || ''}
                    onChange={(e) => {
                      const voice = availableVoices.find(v => v.name === e.target.value);
                      setSelectedVoice(voice || null);
                    }}
                    className="voice-select"
                  >
                    {availableVoices.map((voice, index) => (
                      <option key={index} value={voice.name}>
                        {voice.name} ({voice.lang})
                      </option>
                    ))}
                  </select>
                </label>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* 消息列表 */}
      <div className="messages-container">
        {/* 撤回提示 */}
        {showRecallTip && (
          <div className="recall-tip">
            <span>✓ 消息已撤回</span>
          </div>
        )}
        
        {/* 语音状态指示器 */}
        {isSpeaking && (
          <div className="speech-status">
            <div className="speech-indicator">
              <span className="speech-dot"></span>
              <span className="speech-text">
                {speakingMessageId ? '正在播放消息...' : '正在播放语音...'}
              </span>
              <button 
                className="speech-stop-btn"
                onClick={stopSpeaking}
                title="停止播放"
              >
                ⏹️
              </button>
            </div>
          </div>
        )}
        
        <div className="messages-list">
          {filteredMessages.map((message) => (
            <div
              key={message.id}
              className={`message ${message.type === 'user' ? 'message-user' : 'message-assistant'} ${
                speakingMessageId === message.id ? 'speaking' : ''
              } ${clickToSpeak ? 'clickable' : ''}`}
              onClick={() => handleMessageClick(message)}
              title={clickToSpeak ? '点击播放语音' : ''}
            >
              <div className="message-avatar">
                {message.type === 'user' ? '👤' : '🤖'}
              </div>
              <div className="message-content">
                {editingMessageId === message.id ? (
                  // 编辑模式
                  <div className="message-edit-container">
                    <textarea
                      value={editValue}
                      onChange={(e) => setEditValue(e.target.value)}
                      onKeyPress={handleKeyPress}
                      className="message-edit-input"
                      autoFocus
                    />
                    {editingImage && (
                      <div className="editing-image-preview">
                        <img src={editingImage} alt="编辑图片" className="editing-image" />
                        <button 
                          className="remove-editing-image-btn"
                          onClick={() => setEditingImage(null)}
                          title="移除图片"
                        >
                          ✕
                        </button>
                      </div>
                    )}
                    <div className="edit-actions">
                      <button className="edit-btn save-btn" onClick={editingImage ? saveImageEdit : saveEdit}>
                        ✓
                      </button>
                      <button className="edit-btn cancel-btn" onClick={cancelEdit}>
                        ✕
                      </button>
                    </div>
                  </div>
                ) : (
                  // 正常显示模式
                  <div className="message-bubble">
                    {message.imageUrl && (
                      <div className="message-image-container">
                        <img 
                          src={message.imageUrl} 
                          alt="消息图片" 
                          className="message-image" 
                          onClick={() => setShowImageModal(message.imageUrl || null)}
                        />
                      </div>
                    )}
                    {message.type === 'assistant' ? (
                      <MarkdownMessage content={message.content} />
                    ) : (
                      <span>{message.content}</span>
                    )}
                    {message.type === 'user' && message.canRecall && (
                      <div className="message-actions">
                        <button 
                          className="action-btn-small edit-btn-small"
                          onClick={() => {
                            if (message.imageUrl) {
                              handleEditImage(message.id, message.imageUrl)
                            } else {
                              handleEdit(message.id, message.content)
                            }
                          }}
                          title="编辑消息"
                        >
                          <span>✏️</span>
                        </button>
                        <button 
                          className="action-btn-small recall-btn-small"
                          onClick={() => handleRecall(message.id)}
                          title="撤回消息"
                        >
                          <span>↶</span>
                        </button>
                      </div>
                    )}
                  </div>
                )}
                <div className="message-time">
                  {formatTime(message.timestamp)}
                  {message.type === 'user' && <span className="message-status">✓</span>}
                </div>
              </div>
            </div>
          ))}
          {/* 加载状态指示器 */}
          {isLoading && (
            <div className="message message-assistant">
              <div className="message-avatar">🤖</div>
              <div className="message-content">
                <div className="message-bubble loading">
                  <div className="typing-indicator">
                    <span></span>
                    <span></span>
                    <span></span>
                  </div>
                </div>
              </div>
            </div>
          )}
          <div ref={messagesEndRef} />
        </div>
      </div>

      {/* 图片模态框 */}
      {showImageModal && (
        <div className="image-modal-overlay" onClick={() => setShowImageModal(null)}>
          <div className="image-modal-content" onClick={e => e.stopPropagation()}>
            <button 
              className="image-modal-close"
              onClick={() => setShowImageModal(null)}
            >
              ✕
            </button>
            <img src={showImageModal} alt="大图预览" className="image-modal-image" />
          </div>
        </div>
      )}

      {/* 输入区域 */}
      <div className="input-container">
        <div className="input-wrapper">
          <textarea
            ref={finalInputRef}
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
            onKeyPress={handleKeyPress}
            placeholder="输入消息，按Enter发送，Ctrl+Z撤回..."
            className="message-input"
            rows={1}
            disabled={isLoading}
          />
          <div className="input-actions">
            {/* 表情按钮 */}
            <button 
              className={`action-btn emoji-btn ${showEmojiPicker ? 'active' : ''}`}
              onClick={toggleEmojiPicker}
              title="表情"
              type="button"
            >
              <span>😊</span>
            </button>
            {/* 图片上传按钮 */}
            <button 
              className="action-btn"
              onClick={() => imageInputRef.current?.click()}
              title="上传图片"
            >
              <span>🖼️</span>
            </button>
            {/* 文件上传按钮 */}
            <button 
              className="action-btn"
              onClick={() => fileInputRef.current?.click()}
              title="上传文件"
            >
              <span>📎</span>
            </button>
            {/* 隐藏的文件上传输入框 */}
            <input
              ref={imageInputRef}
              type="file"
              onChange={handleImageUpload}
              style={{ display: 'none' }}
              accept="image/*"
            />
            <input
              ref={fileInputRef}
              type="file"
              onChange={handleFileUpload}
              style={{ display: 'none' }}
              accept="*/*"
            />
            {/* 发送按钮 */}
            <button 
              className={`send-btn ${inputValue.trim() && !isLoading ? 'active' : ''}`}
              onClick={handleSend}
              disabled={!inputValue.trim() || isLoading}
            >
              <span>发送</span>
            </button>
          </div>
        </div>
        
        {/* 图片预览 */}
        {imagePreview && (
          <div className="image-preview">
            <div className="image-preview-header">
              <span>图片预览</span>
              <button 
                className="image-preview-close"
                onClick={removeImage}
                title="移除图片"
              >
                ✕
              </button>
            </div>
            <div className="image-preview-content">
              <img src={imagePreview} alt="预览" className="preview-image" />
              <textarea
                value={inputValue}
                onChange={(e) => setInputValue(e.target.value)}
                placeholder="为图片添加描述..."
                className="image-description-input"
              />
              <button 
                className="send-image-btn"
                onClick={() => sendImageMessage(imagePreview, inputValue)}
              >
                发送图片
              </button>
            </div>
          </div>
        )}

        {/* 表情选择器 */}
        {showEmojiPicker && (
          <div 
            className="emoji-picker" 
            onClick={(e) => e.stopPropagation()}
          >
            <div className="emoji-picker-header">
              <span className="emoji-picker-title">选择表情</span>
              <button 
                className="emoji-picker-close"
                onClick={() => setShowEmojiPicker(false)}
                title="关闭"
              >
                ✕
              </button>
            </div>
            <div className="emoji-grid">
              {[
                // 笑脸
                '😀','😁','😂','🤣','😃','😄','😅','😆','😉','😊','😋','😎','😍','😘','🥰','😗','😙','😚','🙂','🤗','🤩','🤔','🤨','😐','😑','😶','🙄','😏','😣','😥','😮','🤐','😯','😪','😫','🥱','😴','😌','😛','😜','😝','🤤','😒','😓','😔','😕','🙃','🤑','😲','☹️','🙁','😖','😞','😟','😤','😢','😭','😦','😧','😨','😩','🤯','😬','😰','😱','🥵','🥶','😳','🤪','😵','😡','😠','🤬','😷','🤒','🤕','🤢','🤮','🤧','😇','🥳','🥺','🤠','🤡','🤥','🤫','🤭','🧐','🤓','😈','👿','👹','👺','💀','👻','👽','🤖','😺','😸','😹','😻','😼','😽','🙀','😿','😾',
                // 手势
                '👋','🤚','🖐️','✋','🖖','👌','🤏','✌️','🤞','🤟','🤘','🤙','👈','👉','👆','🖕','👇','☝️','👍','👎','✊','👊','🤛','🤜','👏','🙌','👐','🤲','🙏','✍️','💅','🤳','💪','🦾','🦵','🦿','🦶','👂','🦻','👃','🧠','🦷','🦴','👀','��️','👅','👄','💋',
                // 物品/符号
                '❤️','🧡','💛','💚','💙','💜','🖤','🤍','🤎','💔','❣️','💕','💞','💓','💗','💖','💘','💝','💟','💯','💢','💥','💫','💦','💨','🕳️','💣','💬','👁️‍🗨️','🗨️','🗯️','💭','💤','👋','🤚','🖐️','✋','🖖','👌','🤏','✌️','🤞','🤟','🤘','🤙','👈','👉','👆','🖕','👇','☝️','👍','👎','✊','👊','🤛','🤜','👏','🙌','👐','🤲','🙏','✍️','💅','🤳','💪','🦾','🦵','🦿','🦶','👂','🦻','👃','🧠','🦷','🦴','👀','��️','👅','👄','💋',
                // 动物
                '🐶','🐱','🐭','🐹','🐰','🦊','🐻','🐼','🐨','🐯','🦁','🐮','🐷','🐽','🐸','🐵','🙈','🙉','🙊','🐒','🐔','🐧','🐦','🐤','🐣','🐥','🦆','🦅','🦉','🦇','🐺','🐗','🐴','🦄','🐝','🐛','🦋','🐌','🐞','🐜','🦟','🦗','🕷️','🕸️','🦂','🐢','🐍','🦎','🦖','🦕','🐙','🦑','🦐','🦞','🦀','🐡','🐠','🐟','🐬','🐳','🐋','🦈','🐊','🐅','🐆','🦓','🦍','🦧','🐘','🦛','🦏','🐪','🐫','🦙','🦒','🐃','🐂','🐄','🐎','🐖','🐏','🐑','🦌','🐐','🦮','🐕‍🦺','🐩','🐕','🐈','🐈‍⬛','🦝','🦨','🦡','🦦','🦥','🐁','��','🐇','🐿️','🦔',
              ].map((emoji, index) => (
                <button
                  key={index}
                  className="emoji-btn"
                  onClick={(e) => {
                    e.preventDefault()
                    e.stopPropagation()
                    addEmoji(emoji)
                  }}
                  type="button"
                  title={emoji}
                >
                  {emoji}
                </button>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  )
}

export default Chat